package com.mall.common.hibernate.dynamic;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class DynamicStatementDTDEntityResolver implements EntityResolver, Serializable {

	private static final long serialVersionUID = 1L;
	private static final Logger logger = LoggerFactory.getLogger( DynamicStatementDTDEntityResolver.class );
	private static final String hop_dynamic_statement = "http://www.baisha.org/dtd/";

	@Override
	public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
		InputSource source = null; // returning null triggers default behavior
		if ( systemId != null ) {
			logger.debug( "trying to resolve system-id [" + systemId + "]" );
			if ( systemId.startsWith( hop_dynamic_statement ) ) {
				logger.debug( "recognized hop dyanmic statement namespace; attempting to resolve on classpath under org.baisha.framework.hibernate3.dynamic.freemarker/" );
				source = resolveOnClasspath( publicId, systemId, hop_dynamic_statement );
			}
		}
		return source;
	}

	private InputSource resolveOnClasspath(String publicId, String systemId, String nameSpace) {
		InputSource source = null;
		String path = "framework/hibernate/dynamic/" + systemId.substring( nameSpace.length() );
		InputStream dtdstream = resolveInHibernateNamespace( path );
		if ( dtdstream == null ) {
			logger.debug( "unable to locate [" + systemId + "] on classpath" );
			if ( systemId.substring( nameSpace.length() ).indexOf( "2.0" ) > -1 ) {
				logger.error( "don't use old dtds, read the hibernate 3.x migration guide!" );
			}
		}
		else {
			logger.debug( "located [" + systemId + "] in classpath" );
			source = new InputSource( dtdstream );
			source.setPublicId( publicId );
			source.setSystemId( systemId );
		}
		return source;
	}

	protected InputStream resolveInHibernateNamespace(String path) {
		return this.getClass().getClassLoader().getResourceAsStream( path );
	}
	
//	protected InputStream resolveInLocalNamespace(String path) {
//		try {
//			return ConfigHelper.getResourceAsStream( path );
//		} catch ( Throwable t ) {
//			return null;
//		}
//	}

}
